Skip to main content

Dialog: Project Settings: Static Analysis Light

Symbol: _cds_icon_stat_analy_light.png

Function: The dialog activates the checks which are performed with the light version of CODESYS Static Analysis each time code is generated.

Call: Project → Project Settings command, Static Analysis Light category

Tip

You can exclude lines of code from the static code analysis by marking the code with the {analysis ...} pragma or the {attribute 'analysis' := '...'} pragma.

For more information, see: Analyzing Code Statically

Additional Compile Checks

SA0033: Unused variables

Detects variables which are declared but not used within the compiled program code

For GVL variables: If multiple applications exist in a project, then only the objects below the currently active application are affected. If there is only one application, then the objects in the POUs view are also affected.

SA0028: Overlapping memory areas

Detects the lines of code where two or more variables reserve the same memory

For example, this occurs for the following declarations: var1 AT %QB21: INT and var2 AT %QD5: DWORD. In this case, both variables use byte 21, which means that the memory range of the variables overlap.

SA0006: Write access from several tasks

Detects variables which are written to by more than one task

SA0004: Multiple write access on output

Detects outputs which are written to more than one location

Note: An error is not issued when an output variable (VAR_IN_OUT) is written to in different branches of IF and CASE statements.

Note: A pragma cannot disable this rule.

SA0027: Multiple uses of identifiers

Detects multiple uses of a name/identifier for a variable or an object (POU) within the scope of a project

. The following cases are detected:
  • The name of an enumeration constant is the same as in another enumeration in the application or used in an included library.

  • The name of a variable is the same as the name of an object in the application or the name of an integrated library.

  • The name of a variable is the same as the name of an enumeration constant in an enumeration in the application or the name of an integrated library.

  • The name of an object is the same as the name of another object in the application.

  • The name of a variable is the same as the name of a method.

  • The name of an object is the same as the name of a superordinate object ("parent object").

SA0167: Report temporary FunctionBlock instances

The check detects function block instances which are declared as temporary variables. This affects instances which are declared in a method or function or as VAR_TEMP, and therefore are reinitialized in each processing cycle or for each POU call.

SA0175: Suspicious operation on string

Inactive by default

Detects code locations which are suspicious for UTF-8 encoding

The following constructs are included:

  • Index access to a single-byte string

    Example: str[2]

    Message: Suspicious operation on string: Index access '<expression>'

  • Address access to a single-byte string

    Example: ADR(str)

    Message: Suspicious operation on string: Possible index access '<expression>'

  • Calling a string function of the standard library except CONCAT and LEN

    Message: Suspicious operation on string: Possible index access '<expression>'

  • Single-byte literal containing non-ASCII characters

    Example:

    str := '99€';

    str := 'Ä';

    Message: Suspicious operation on string: Literal '<literal>' contains non-ASCII characters

Depending on the result of the check, it is advisable not to enable the UTF8 Encoding for STRING compile option.

For more information, see: Compile options

Example 544. Examples

SA0003: Empty statements

;
(* Comment *);
iVar;

SA0006: Concurrent access

FUNCTION_BLOCK ADD_FB
g_iTemp1 := g_iTemp1 + INT#1;
PROGRAM PLC_PRG  //controlled by MainTask
g_iTemp1 := g_iTemp1 + INT#2;
g_xTemp2 := g_iTemp1 > INT#10;
PROGRAM PLC_PRG_1  //controlled by SubTask
g_iTemp1 := g_iTemp1 - INT#3;
g_xTemp2 := g_iTemp1 < INT#-10;

SA0004: Multiple write access on output

VAR_GLOBAL
    g_xVar AT %QX0.0 : BOOL ;
    g_iTest AT %QW0 : INT ;
END_VAR
PROGRAM PLC_PRG
IF iCondition < INT#0 THEN
    g_xVar := TRUE;
    g_iTest := INT#12;
END_IF
CASE iCondition OF
    INT#1:
        g_xVar := FALSE;
    INT#2:
        g_iTest := INT#11;
    ELSE
        g_xVar := TRUE;
        g_iTest := INT#9;
END_CASE

SA0006: Write access from several tasks

FUNCTION_BLOCK ADD_FB
g_iTemp1 := g_iTemp1 + INT#1;
PROGRAM PLC_PRG  // Controlled by MainTask
g_iTemp1 := g_iTemp1 + INT#2;
g_xTemp2 := g_iTemp1 > INT#10;
PROGRAM PLC_PRG_1  //Controlled by SubTask
g_iTemp1 := g_iTemp1 - INT#3;
g_xTemp2 := g_iTemp1 < INT#-10;

SA0027: Multiple use of name

PROGRAM PLC_PRG
VAR
    ton : INT; // error SA0027
END_VAR

SA0029: Notation in code different to declaration

A PLC_PRG POU and a fnc (function) POU exist in the device tree.

PROGRAM PLC_PRG
VAR
    iVar:INT;
    _123test_var_: INT;
END_VAR
ivar := iVar + 1; // notation different to that in the declaration part ->   SA0029
_123TEST_var_ := _123test_var_INT; // notation different to that in the declaration part ->   SA0029
Fnc(); // notation different to that in the devices tree ->   SA0029

SA0167: Report temporary FunctionBlock instances

PROGRAM PLC_PRG
VAR
END_VAR
VAR_TEMP
    yafb: AFB;
END_VAR

FUNCTION Fun : INT
VAR_INPUT
END_VAR
VAR
    funafb: AFB;
END_VAR
METHOD METH: INT
VAR_INPUT
END_VAR
VAR
    methafb: AFB;
END_VAR


For more information, see: Analyzing Code Statically